package com.zhiche.lisa.bms.service.price.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.price.PriceIncomingMapper;
import com.zhiche.lisa.bms.dao.model.price.PriceIncoming;
import com.zhiche.lisa.bms.pojo.vo.util.OrderAssignVO;
import com.zhiche.lisa.bms.pojo.vo.util.ShipOrderItemVO;
import com.zhiche.lisa.bms.pojo.vo.util.ShipTaskVO;
import com.zhiche.lisa.bms.service.price.PriceIncomingService;
import com.zhiche.lisa.bms.service.utils.OmsUtil;
import com.zhiche.lisa.bms.service.utils.OtmUtil;
import com.zhiche.lisa.bms.service.utils.TmsUtil;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 收入价格 服务实现类
 * </p>
 */
@Service
public class PriceIncomingServiceImpl extends ServiceImpl<PriceIncomingMapper, PriceIncoming> implements PriceIncomingService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PriceIncomingServiceImpl.class);
    @Autowired
    private TmsUtil tmsUtil;

    @Autowired
    private OmsUtil omsUtil;

    @Autowired
    private OtmUtil otmUtil;

    @Value("${lisa.socketTimeout}")
    private int socketTimeout;

    @Value("${lisa.integration.getPriceAndMilesUrl}")
    private String getPriceAndMilesUrl;

    @Value("${lisa.integration.url}")
    private String integrationUrl;

    /**
     * 查询条件
     *
     * @param condition
     * @return
     */
    private EntityWrapper<PriceIncoming> queryCheck(Map<String, Object> condition) {
        EntityWrapper<PriceIncoming> ew = new EntityWrapper<>();
        ew.orderBy("gmt_create desc, id desc");
        if (!CollectionUtils.isEmpty(condition)) {
            //遍历条件
            for (Map.Entry<String, Object> entry : condition.entrySet()) {
                if (!Strings.isNullOrEmpty(entry.getKey())) {
                    //订单号
                    if ("orderCode".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.eq("order_code", entry.getValue());
                    //客户
                    if ("customerName".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.like("customer_name", String.valueOf(entry.getValue()));
                    //订单号或者车架号
                    if ("orderCodeOritemUid".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue())) {
                        ew.andNew().like("order_code", String.valueOf(entry.getValue())).or().
                                like("item_uid", String.valueOf(entry.getValue()));
                    }
                    //下单开始时间
                    if ("beginDate".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.ge("gmt_create", entry.getValue());
                    //下单结束时间
                    if ("endDate".equals(entry.getKey()) && !StringUtils.isEmpty(entry.getValue()))
                        ew.le("gmt_create", entry.getValue());
                }
            }
        }
        ew.andNew().eq("is_delete", 0).or().isNull("is_delete");
        return ew;
    }

    @Override
    public Page<PriceIncoming> queryPriceIncomingPage(Page<PriceIncoming> page) {
        if (null == page) return null;
        EntityWrapper<PriceIncoming> ew = this.queryCheck(page.getCondition());
        //清空page附加条件值
        page.setCondition(Maps.newHashMap());
        page.setRecords(baseMapper.selectPage(page, ew));
        return page;
    }

    @Override
    public List<PriceIncoming> queryPricePurchaseList(Map<String, Object> condition) {
        EntityWrapper<PriceIncoming> ew = this.queryCheck(condition);
        return baseMapper.selectList(ew);
    }

    @Override
    public boolean insertPriceIncoming(PriceIncoming obj) {
        if (!StringUtils.hasText(obj.getOrderCode()) || ObjectUtils.isEmpty(obj.getOrderItemId()))
            throw new BaseException("订单编号或订单明细编号，不能为空！");
        boolean result = this.insert(obj);
        if (!result) throw new BaseException("新增收入价格失败！");
        return result;
    }


    @Override
    public List<PriceIncoming> queryCustomerlist(String customerName) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("customerName", customerName);

        EntityWrapper<PriceIncoming> ew = this.queryCheck(condition);
        ew.groupBy("customer_name");
        List<PriceIncoming> result = this.selectList(ew);
        return result;
    }

    @Override
    public boolean deletePriceIncoming(PriceIncoming obj) {
        if (!StringUtils.hasText(obj.getOrderCode())) {
            throw new BaseException("订单编号，不能为空！");
        }
        EntityWrapper ew = new EntityWrapper();
        ew.eq("order_code", obj.getOrderCode());
        boolean result = this.delete(ew);
        if (!result) throw new BaseException("删除收入价格失败！");
        return result;
    }

    @Override
    public boolean updatePriceIncoming(PriceIncoming obj) {
        if (!StringUtils.hasText(obj.getOrderCode()) || ObjectUtils.isEmpty(obj.getOrderItemId()))
            throw new BaseException("订单编号或订单明细编号，不能为空！");
        int isDelete = obj.getIsDelete() >= 1 ? 1 : 0;
        obj.setIsDelete(isDelete);
        EntityWrapper ew = new EntityWrapper();
        ew.eq("order_code", obj.getOrderCode()).and().eq("order_item_id", obj.getOrderItemId());
        boolean result = this.update(obj, ew);
        if (!result) throw new BaseException("修改收入价格失败！");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateIncomingPriceByTaskCode(String taskCode, Long shipOrderItemId, BigDecimal incomingSinglePrice, BigDecimal mileage, String token) {
        if (!StringUtils.hasText(taskCode)) {
            throw new BaseException("运输任务编号，不能为空！");
        }
        if (ObjectUtils.isEmpty(shipOrderItemId)) {
            throw new BaseException("运单货物明细ID，不能为空！");
        }
        if (ObjectUtils.isEmpty(incomingSinglePrice)) {
            throw new BaseException("执行单价，不能为空！");
        }
        if (ObjectUtils.isEmpty(mileage)) {
            throw new BaseException("执行公里数，不能为空！");
        }
        if (!StringUtils.hasText(token)) {
            throw new BaseException("token鉴权，不能为空！");
        }
        //根据运输任务编号得到订单编号
        String orderCode = this.getOrderCodeByTaskCode(taskCode, token);
        //根据订单编号和订单货物明细ID，得到一条订单明细
        PriceIncoming priceIncomingData = this.getPriceIncomingByOrderCodeAdnOrderItemId(orderCode, shipOrderItemId, token);
        //拿到运输订单号
        if (Objects.isNull(priceIncomingData)) throw new BaseException("运输订单不存在");
        String itemSourceKey = priceIncomingData.getItemSourceKey();

        EntityWrapper ew = new EntityWrapper();
        ew.eq("item_source_key", itemSourceKey);
        PriceIncoming incoming = new PriceIncoming();
        incoming.setActIncomingPrice(incomingSinglePrice);
        boolean updateResult = this.update(incoming, ew);

        //根据运输订单号，开始向OTM系统推送执行价格
        RestfulResponse<String> otmResult = otmUtil.exportPrice(itemSourceKey, incomingSinglePrice, mileage, token);
        if (Objects.isNull(otmResult) || otmResult.getCode() != 0) {
            throw new BaseException("向中联结算系统推送价格失败！");
        }
        return updateResult;
    }

    /**
     * 根据运输任务编号得到订单编号
     *
     * @param taskCode 运输任务编号
     * @return
     */
    private String getOrderCodeByTaskCode(String taskCode, String token) {
        //根据taskCode,得到一条运输任务数据
        RestfulResponse<ShipTaskVO> shipTaskByCode = tmsUtil.getShipTaskByCode(taskCode, token);
        if (Objects.isNull(shipTaskByCode) || shipTaskByCode.getCode() != 0) {
            return null;
        }
        //拿到运输任务的运单编号
        String shipOrderCode = shipTaskByCode.getData().getShipOrderCode();

        //根据运单编号,得到订单下发表的一条数据
        RestfulResponse<OrderAssignVO> orderAssignByConsignCode = omsUtil.getOrderAssignByConsignCode(shipOrderCode, token);
        if (Objects.isNull(orderAssignByConsignCode) || orderAssignByConsignCode.getCode() != 0) {
            return null;
        }
        //拿到订单下发的订单编号
        String orderCode = orderAssignByConsignCode.getData().getOrderCode();
        return orderCode;
    }

    /**
     * 根据订单编号和订单货物明细ID得到[收入价格表]一条订单明细
     *
     * @param orderCode       订单编号
     * @param shipOrderItemId 运单货物明细ID
     * @return
     */
    private PriceIncoming getPriceIncomingByOrderCodeAdnOrderItemId(String orderCode, Long shipOrderItemId, String token) {
        //根据shipOrderItemId,得到一条运单货物明细
        RestfulResponse<ShipOrderItemVO> shipOrderItemById = tmsUtil.getShipOrderItemById(shipOrderItemId, token);
        if (shipOrderItemById == null || ObjectUtils.isEmpty(shipOrderItemById.getData())) {
            return null;
        }
        //拿到运单货物明细表的订单货物编号
        Long orderItemId = shipOrderItemById.getData().getOrderItemId();
        //开始条件过滤
        EntityWrapper ew = new EntityWrapper();
        ew.eq("order_code", orderCode).eq("order_item_id", orderItemId);
        //拿到收入价格表的一条订单明细
        PriceIncoming priceIncomingData = this.selectOne(ew);
        return priceIncomingData;
    }

    /**
     * 收入重新获取更新一次价格为空的数据
     */
    @Override
    public void getPriceIncoming() {
        List<PriceIncoming> priceIncomings = baseMapper.getPriceIncomingNotenant();
        for (PriceIncoming priceIncoming : priceIncomings) {
            LOGGER.info("getPriceIncoming params {}", JSONObject.toJSONString(priceIncoming));
            Map<String, String> orderno = new HashMap<>();
            orderno.put("orderno", priceIncoming.getItemSourceKey());
            priceIncoming.setGmtModify(new Date());
            this.updateById(priceIncoming);
            String priceAndMiles = null;
            try {
                LOGGER.info("getPriceIncoming url:{},param:{}", integrationUrl + getPriceAndMilesUrl, JSON.toJSONString(orderno));
                priceAndMiles = HttpClientUtil.postJson(integrationUrl + getPriceAndMilesUrl, null,
                        JSON.toJSONString(orderno), socketTimeout);
                LOGGER.info("getPriceIncoming url:{},param:{},result:{}", integrationUrl + getPriceAndMilesUrl, JSON.toJSONString(orderno), priceAndMiles);
            } catch (Exception e) {
                LOGGER.error("getPriceIncoming url:{},param:{},超时异常:{}", integrationUrl + getPriceAndMilesUrl, JSON.toJSONString(orderno), e);
            }
            if (!StringUtils.isEmpty(priceAndMiles)) {
                JSONObject jsonObject = JSONObject.parseObject(priceAndMiles);
                if (jsonObject.getIntValue("code") == 0) {
                    //暂估价
                    priceIncoming.setEstIncomingPrice(jsonObject.getJSONObject("data").getBigDecimal("price"));
                    //计价里程
                    priceIncoming.setMileage(jsonObject.getJSONObject("data").getBigDecimal("miles"));
                    this.updateById(priceIncoming);
                } else {
                    LOGGER.error("获取价格里程失败" + jsonObject.getString("message"));
                }
            } else {
                LOGGER.error("连接OTM获取价格里程失败");
            }
        }
    }

}
